#########################################################################
# Time-stamp: <05/06/16 12:23:02 ostolop>
#########################################################################
package EP::EPC::Core::Signature_Algorithm;

use strict;

use EP::Config;
use EP::Common;
use EP::Common::General;

use EP::EPC::Core;
use EP::EPC::Core::Component;

use EP::Rclient;

use Text::Template;
use CGI qw/:standard/;

use File::Temp;
use File::Basename;

our @ISA = qw ( EP::EPC::Core::Component );

sub process_component {
  my $self = shift;

  my $result = $self->run_SigAlg();

  my $dataset_folder_path = $EP::Config::h->{EPNG_USRDATA_PATH} . "/" . $self->{src_dataset}->folder->location;
  my $output_www_base = "$EP::Config::h->{EPNG_USRDATA_URL}/" . $self->{src_dataset}->folder->location . "/";

  my $htmlfile = new File::Temp ( DIR => $dataset_folder_path, SUFFIX => ".html", UNLINK => 0 );
  my $htmlfile_url = $output_www_base . basename ( $htmlfile );

  print $htmlfile $result;
  close $htmlfile;

  my $process_result = { html => $htmlfile_url,
       src_dataset_id => $self->{src_dataset}->id,
       dst_dataset_id => $self->{src_dataset}->id
           };

  $self->{CD}->{process_result} = $process_result;
  return $self->record_analysis_history ();
}

sub run_SigAlg {
  my $self = shift;

  throw EP::Common::Error ( -value => AFFY_TRANSFORM_RAW_DATA ) if $self->{src_dataset}->type eq "affy";

  my $dataset_folder_path = $EP::Config::h->{EPNG_USRDATA_PATH} . "/" . $self->{src_dataset}->folder->location;

  ##################################################################################################################
  # Parse the input gene orfs into a vector of indices
  ##################################################################################################################
  my $inputGenes = $self->{query}->param("inputGenes");
  my @inGenes = split /\r\n|\r|\n/, $inputGenes;
  warn "Looking for @inGenes" if DEBUG;

  my @RgeneList;
  my @genes;

  open ROWS, $dataset_folder_path . "/" . $self->{src_dataset}->filename . ".rows";
  <ROWS>;     # skip row names line

  while (<ROWS>) {
    chomp;

    my ($row_id, @annots) = split /\t/, $_;
    $genes[$row_id] = join ( ", ", @annots );

    foreach my $ingene ( @inGenes ) {
      if ( grep { $_ =~ /$ingene/ } @annots ) {
        push @RgeneList, $row_id + 1; # R indices are 1-based (so, add 1)
  warn "Found gene $ingene at row $row_id" if DEBUG;
#        last;
      }
    }
  }
  close ROWS;

  die "Couldn't find $inputGenes in the dataset!" if @RgeneList == 0;


  ##################################################################################################################
  # Read in the conditions annotation
  ##################################################################################################################
  my @conds;
  open COLS, $dataset_folder_path . "/" . $self->{src_dataset}->filename . ".columns";
  while (<COLS>) {
    chomp;

    my ($col_id, @annots) = split /\t/, $_;
    $conds[$col_id] = join ( ", ", @annots );
  }
  close COLS;

  if ( $self->{query}->param ( "sig_algorithm" ) eq "PSA" ) {
  ##################################################################################################################
  #-----------------------------------------------------------------------------------------------------------------
  # PLAIN SIGNATURE ALGORITHM
  #-----------------------------------------------------------------------------------------------------------------
  ##################################################################################################################
  #-----------------------------------------------------------------------------------------------------------------
  # Parameters to be sent to the template R file
  #-----------------------------------------------------------------------------------------------------------------
  my $tmpl_values =
        { app_root       => $EP::Config::h->{ROOT}
        , src            => $dataset_folder_path . "/" . $self->{src_dataset}->filename . ".bin"
        , srcrowannot    => $dataset_folder_path . "/" . $self->{src_dataset}->filename . ".rows"
        , srccolannot    => $dataset_folder_path . "/" . $self->{src_dataset}->filename . ".columns"
        , filename       => $self->{src_dataset}->filename
        , outputdir      => $dataset_folder_path
        , condThreshold  => $self->{query}->param("tc")
        , geneThreshold  => $self->{query}->param("tg")
        , geneList       => "c(" . join ( ",", @RgeneList ) . ")"
        };

  #-----------------------------------------------------------------------------------------------------------------
  # parse the template R file and execute it in R
  #-----------------------------------------------------------------------------------------------------------------
  my ($genes_file, $genescores_file, $conds_file, $condscores_file)
        = EP::Rclient->R( parse_template( $tmpl_values, "$EP::Config::h->{TMPL}/R/ep.run_SigAlg.tmpl.R" ) );

    #-----------------------------------------------------------------------------------------------------------------
    # HTML output
    #-----------------------------------------------------------------------------------------------------------------
    my @outputGenes      = get_outputGenes ( $genes_file, $genescores_file, \@genes );
    my @outputConditions = get_outputConditions ( $conds_file, $condscores_file, \@conds);

#   my $image_filename;
#   ($image_filename) = $Rout =~ /ReccImage: (.*?)\"/;
    my $og = join ( " ", @outputGenes );
    my $oc = join ( " ", @outputConditions );

    my $HTML_OUTPUT = "";
    $HTML_OUTPUT .= start_html( -title => "TST",
              -target => "_blank",
              -bgcolor => "white"
            );
    $HTML_OUTPUT .= h3("Signature Algorithm Results");
    $HTML_OUTPUT .= h4("Parameters");
    $HTML_OUTPUT .= "Condition threshold: ".$self->{query}->param("tc").br();
    $HTML_OUTPUT .= "Gene threshold: ".$self->{query}->param("tg").hr();
  
    $HTML_OUTPUT .= h4("Input genes");
    $HTML_OUTPUT .= textarea("inputGenes",join(" ",$self->{query}->param("inputGenes")),5,50).hr().hr();
  
    $HTML_OUTPUT .=h4("Signature Algorithm Output");
    $HTML_OUTPUT .="<table width=100%><tr><td><font color=#0000ff><strong>Output genes</strong></font> (Score:ORF)<br>";
    $HTML_OUTPUT .= textarea ( "genes", $og, 20, 30 );
    $HTML_OUTPUT .="</td><td><font color=#0000ff><strong>Output Conditions</strong></font> (Score: Condition)<BR>";
    $HTML_OUTPUT .= textarea ( "genes2", $oc, 20, 30 );
    $HTML_OUTPUT .="</td></tr></table>".hr();
    $HTML_OUTPUT .= end_html();

    return $HTML_OUTPUT;

  } elsif ( $self->{query}->param ( "sig_algorithm" ) eq "RSA" ) {
  ##################################################################################################################
  #-----------------------------------------------------------------------------------------------------------------
  # RECURRENT SIGNATURE ALGORITHM
  #-----------------------------------------------------------------------------------------------------------------
  ##################################################################################################################
  #-----------------------------------------------------------------------------------------------------------------
  # Parameters to be sent to the template R file
  #-----------------------------------------------------------------------------------------------------------------
  my $tmpl_values = { app_root          => $EP::Config::h->{ROOT},
          src                => $dataset_folder_path . "/" . $self->{src_dataset}->filename . ".bin",
          srcrowannot        => $dataset_folder_path . "/" . $self->{src_dataset}->filename . ".rows",
          srccolannot        => $dataset_folder_path . "/" . $self->{src_dataset}->filename . ".columns",
          filename           => $self->{src_dataset}->filename,
          outputdir          => $dataset_folder_path,
          condThreshold      => $self->{query}->param("tc"),
          geneThreshold      => $self->{query}->param("tg"),
          nDerivSets         => $self->{query}->param("nDerivSets"),
          fractionFromInput  => $self->{query}->param("fractionFromInput"),
          fractionFromGenome => $self->{query}->param("fractionFromGenome"),
          minRecc            => $self->{query}->param("minRecc"),
          geneList           => "c(" . join ( ",", @RgeneList ) . ")",
        };

  #-----------------------------------------------------------------------------------------------------------------
  # parse the template R file and execute it in R
  #-----------------------------------------------------------------------------------------------------------------
  warn parse_template( $tmpl_values, "$EP::Config::h->{TMPL}/R/ep.run_RecSigAlg.tmpl.R" );
  my ($genes_file, $genescores_file, $conds_file, $condscores_file)
        = EP::Rclient->R( parse_template( $tmpl_values, "$EP::Config::h->{TMPL}/R/ep.run_RecSigAlg.tmpl.R" ) );

  #-----------------------------------------------------------------------------------------------------------------
  # HTML output
  #-----------------------------------------------------------------------------------------------------------------
  my @outputGenes      = get_outputGenes ( $genes_file, $genescores_file, \@genes );
  my @outputConditions = get_outputConditions ( $conds_file, $condscores_file, \@conds);

# TO DO
# my $image_filename;
# ($image_filename) = $Rout =~ /ReccImage: (.*?)\"/;
  my $og = join ( " ", @outputGenes );
  my $oc = join ( " ", @outputConditions );

  my $HTML_OUTPUT = "";
  $HTML_OUTPUT .= start_html( -title => "TST",
            -target => "_blank",
            -bgcolor => "white"
          );
  my $nGenesInput = scalar @RgeneList;
  my $nFromInput = int ($self->{query}->param("fractionFromInput"))*$nGenesInput/100;
  my $nFromGenome = int ($self->{query}->param("fractionFromGenome"))*$nGenesInput/100;

  $HTML_OUTPUT .= h4("Recurrent Signature Parameters");
  $HTML_OUTPUT .= "Condition threshold: ".$self->{query}->param("tc").br();
  $HTML_OUTPUT .= "Gene threshold: ".$self->{query}->param("tg").br().br();
  $HTML_OUTPUT .= "Number of submitted input genes: ".$nGenesInput.br().br();
  $HTML_OUTPUT .= "Number of genes taken from input for each derivative set: ".$nFromInput.br();
  $HTML_OUTPUT .= "Number of genes taken from genome for each derivative set: ".$nFromGenome.br();
  $HTML_OUTPUT .= "Number of derivative sets: ".$self->{query}->param("nDerivSets").hr();


  $HTML_OUTPUT .= h4("Input genes");
  $HTML_OUTPUT .= textarea("inputGenes",join(" ",$self->{query}->param("inputGenes")),5,50).hr().hr();

# TO DO
# my $www_image_file = "$EP::Config::h->{EPNG_USRDATA_URL}/" . $self->{src_dataset}->folder->location . "/SigAlg$image_filename";
  $HTML_OUTPUT .=h3("<font color=#0000ff>Submitted genes</font> vs <font color=#ff0000>random control</font>");
# $HTML_OUTPUT .= img ({src=>$www_image_file});
  $HTML_OUTPUT .="<table width=100%><tr><td><font color=#0000ff><strong>Output genes</strong></font> (Score:ORF)<br>";
  $HTML_OUTPUT .= textarea ( "genes", $og, 20, 30 );
  $HTML_OUTPUT .="</td><td><font color=#0000ff><strong>Output Conditions</strong></font> (Score: Condition)<BR>";
  $HTML_OUTPUT .= textarea ( "genes2", $oc, 20, 30 );
  $HTML_OUTPUT .="</td></tr></table>".hr();
  $HTML_OUTPUT .= end_html();

  return $HTML_OUTPUT;
  }


}

sub parse_template {
  my ($tmpl_values, $src) = @_;

  my $template = Text::Template->new(TYPE => "FILE", SOURCE => $src );
  return $template->fill_in ( HASH => $tmpl_values );
}

sub get_outputGenes {
  my ( $genes_file, $genescores_file, $genes ) = @_;
  my @gene_ids;
  my @scores;

  open SCORES, $genescores_file or die "Couldn't open GeneScores file '$genescores_file'";
  while (<SCORES>) {
    chomp;
    push @scores, $_;
  }
  close SCORES;

  open GENES, $genes_file;
  while (<GENES>) {
    chomp;
    push @gene_ids, $scores[$. - 1] . ":" . $$genes[$_ - 1]."\n" if defined $$genes[$_ - 1];
  }
  close GENES;


  return @gene_ids;
}

sub get_outputConditions {
  my ( $conds_file, $condscores_file, $conds ) = @_;
  my @cond_ids;
  my @scores;

  open SCORES, $conds_file;
  while (<SCORES>) {
    chomp;
    push @scores, $_;
  }
  close SCORES;

  open CONDITIONS, $conds_file or die "Couldn't open conditions file '$conds_file'";
  while (<CONDITIONS>) {
    chomp;
    push @cond_ids, $scores[$. - 1] . ":" . $$conds[$_ - 1]."\n" if defined $$conds[$_ - 1];
  }
  close CONDITIONS;

  return @cond_ids;
}




1;
